package com.example.java_gobang.api;


import com.example.java_gobang.common.AppVariable;
import com.example.java_gobang.game.MatchRequest;
import com.example.java_gobang.game.MatchResponse;
import com.example.java_gobang.game.Matcher;
import com.example.java_gobang.game.OnlineUserManger;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

// 处理匹配功能中的 websocket 请求
@Component
public class MatchAPI extends TextWebSocketHandler {
    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManger onlineUserManger;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 上线, 加入到 onlineUserManger 中
        try {
            // 获取该用户信息
            User user = (User) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
            // 判断当前用户是否已经在线，不允许多开

            if(onlineUserManger.getFromGameHall(user.getUserId()) != null
                    || onlineUserManger.getFromGameRoom(user.getUserId()) != null){
                // 已经在线
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setReason("检测到该账号已经在线了");
                response.setMessage("repeatConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                //session.close();
                return;
            }

            // 把玩家设置为在线状态
            onlineUserManger.enterGameHall(user.getUserId(),session);
            System.out.println("玩家 " + user.getUsername() + " 进入游戏大厅");
        }catch (NullPointerException e){
            System.out.println("用户未登录[afterConnectionEstablished]");
//            e.printStackTrace();
            // 用户未登录
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("未登录！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理开始/停止匹配请求
        User user = (User) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
        // 获取客户端给服务器发送的数据
        String payload = message.getPayload();
        // 将 JSON 格式的字符串转化为 Java 对象
        MatchRequest request = objectMapper.readValue(payload,MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if(request.getMessage().equals("startMatch")){
            // 进入匹配队列
            // 把当前用户加入匹配队列
            matcher.add(user);
            // 把玩家信息放入匹配队列后就返回响应给前端
            response.setOk(true);
            response.setMessage("startMatch");
        } else if(request.getMessage().equals("stopMatch")){
            // 退出匹配队列
            // 把玩家从匹配队列中移除
            matcher.remove(user);
            // 返回响应
            response.setOk(true);
            response.setMessage("stopMatch");
        } else {
            // 非法情况
            response.setOk(false);
            response.setReason("非法的匹配请求");
        }
        String jsonString = objectMapper.writeValueAsString(response);
        session.sendMessage(new TextMessage(jsonString));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            // 玩家下线，从 OnlineUserManager 中删除
            User user = (User) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
            WebSocketSession temSession = onlineUserManger.getFromGameHall(user.getUserId());
            if(temSession == session){
                onlineUserManger.exitGameHall(user.getUserId());
            }
            // 玩家在匹配中连接断开，将其移除匹配队列
            matcher.remove(user);
        } catch (NullPointerException e){
            System.out.println("用户未登录[handleTransportError]");
//            e.printStackTrace();
//            // 用户未登录
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("未登录！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            // 玩家下线，从 OnlineUserManager 中删除
            User user = (User) session.getAttributes().get(AppVariable.USER_SESSION_KEY);
            WebSocketSession temSession = onlineUserManger.getFromGameHall(user.getUserId());
            if(temSession == session){
                onlineUserManger.exitGameHall(user.getUserId());
            }
            // 玩家在匹配中连接断开，将其移除匹配队列
            matcher.remove(user);
        } catch (NullPointerException e){
            System.out.println("用户未登录[afterConnectionClosed]");
//            e.printStackTrace();
//            // 用户未登录
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setReason("未登录！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }
}
